package level.editor.state;

import level.editor.command.Command;
import level.editor.command.RequiresModify;
import level.editor.command.RequiresModule;
import level.editor.command.RequiresUpdate;
import level.editor.mediator.Mediator;
import level.editor.mediator.Module;
import level.editor.window.Window;
import level.state.State;
import level.state.StateHandler;
import level.state.StateMemento;
import level.state.StateReader;

/*
 * Controls other module's interactions with the state. The state holds all
 * information required by the engine to create the level. It is meant to be
 * expansible.
 */

public class StateModule extends Module
{
	private State state;
	private StateMemento memento;
	private Window window;
	private Boolean modified;

	public StateModule(Mediator mediator)
	{
		super(mediator, "StateModule");
	}

	public void init(Window window)
	{
		this.window = window;
		modified = false;
		state = new State();
		StateReader.initiateBlankState(state, null);
		resetMemento();
		update();
	}

	public void resetMemento()
	{
		memento = new StateMemento(StateHandler.copy(state));
	}

	public StateMemento getMemento()
	{
		return memento;
	}

	public void setState(State state)
	{
		this.state = state;
	}

	public State getState()
	{
		return state;
	}

	public void setModified(Boolean modified)
	{
		this.modified = modified;
	}

	public Boolean isModified()
	{
		return modified;
	}

	public Window getWindow()
	{
		return window;
	}

	public void createMemento()
	{
		memento.add(StateHandler.copy(state));
	}

	@Override
	public void pushDownCommand(Command command)
	{
		if (command instanceof RequiresModify)
			setModified(true);

		if (command instanceof RequiresModule)
			((RequiresModule) command).execute(this);

		if (command instanceof RequiresUpdate)
			update();
	}

	private void update()
	{
		memento.updateFile(state.getFile());
		pushUpCommand(new UpdateStateCommand(this));
		pushUpCommand(new UpdateMenuCommand(this));
	}
}
